home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 001 / _au2snd / !au2snd / c / au2snd
Text File  |  1992-07-30  |  6KB  |  266 lines

  1. /************************************************************************/
  2. /* au2snd.c - Convert sampled audio files in uLAW format to signed      */
  3. /*            eight bit ones for Archimedes.                            */
  4. /*            Send comments to:  jhowat@waikato.ac.nz                   */
  5. /************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <limits.h>
  11. #include "os.h"
  12. #include "swis.h"
  13.  
  14. #define DEFAULT_SKIP 32
  15. #define SAMPLE_FILETYPE 0xD3C
  16.  
  17.  
  18. /*** convert uLAW format ch into two's complement ***/
  19.  
  20. int cvtback(unsigned int ch)
  21. {
  22.     int tmp ;
  23.     tmp = 15 - (ch & 0x0F) ;
  24.     switch(ch & 0x70)
  25.     {
  26.         case 0x70 : tmp = 2 * tmp ;
  27.                     break ;
  28.         case 0x60 : tmp = 4 * tmp + 32 ;
  29.                     break ;
  30.         case 0x50 : tmp = 8 * tmp + 96 ;
  31.                     break ;
  32.         case 0x40 : tmp = 16 * tmp + 224 ;
  33.                     break ;
  34.         case 0x30 : tmp = 32 * tmp + 480 ;
  35.                     break ;
  36.         case 0x20 : tmp = 64 * tmp + 992 ;
  37.                     break ;
  38.         case 0x10 : tmp = 128 * tmp + 2016 ;
  39.                     break ;
  40.         case 0x00 : tmp = 256 * tmp + 4064 ;
  41.                     break ;
  42.     }
  43.     if (!(ch & 0x80)) tmp = -tmp ;
  44.  
  45.     return (tmp/4);
  46. }
  47.  
  48.  
  49. void usage(void)
  50. {
  51.         fprintf(stderr, "Usage: au2snd <infile> [-s [<count>]] <outfile>\n\n");
  52.         fprintf(stderr, "       The -s switch makes au2snd skip <count>\n");
  53.         fprintf(stderr, "       bytes from the beginning of the '.au' file.\n");
  54.         fprintf(stderr, "       If no count is given then %i is used.\n\n",DEFAULT_SKIP);
  55.         exit(1);
  56. }
  57.  
  58. int main(argc, argv)
  59. int argc;
  60. char *argv[];
  61. {
  62.     int ch;
  63.     FILE *infile, *outfile;
  64.     int amplif ;
  65.     int i;
  66.     int maxch, minch;
  67.     int skipflag;
  68.     int skipcount;
  69.     int file_length, new_length;
  70.     os_regset my_registers;
  71.     unsigned char *conv_buffer;
  72.     os_error *the_error;
  73.  
  74.     fprintf(stderr, "\nau2snd: V2.00   Copyright (C) Jason Howat  25 June 1992\n");
  75.     fprintf(stderr, "        Auto-amplification version\n\n");
  76.  
  77.     if ((argc < 3) || (argc > 5))
  78.     {
  79.         usage();
  80.     }
  81.     if ((infile = fopen(argv[1], "rb")) == NULL)
  82.     {
  83.         fprintf(stderr,"au2snd: Error opening %s\n",argv[1]);
  84.         exit(1);
  85.     }
  86.  
  87.     /* Read in the length of the file to be converted */
  88.  
  89.     my_registers.r[0] = 5;
  90.     my_registers.r[1] = (int) argv[1];
  91.  
  92.     os_swi(OS_File, &my_registers);
  93.  
  94.     file_length = my_registers.r[4];
  95.  
  96.     fprintf(stderr, "au2snd: Input file is %d byte", file_length);
  97.     if (file_length == 1)
  98.     {
  99.         fprintf(stderr, " long.\n");
  100.     }
  101.     else
  102.     {
  103.         fprintf(stderr, "s long.\n");
  104.     }
  105.  
  106.     skipflag = FALSE;
  107.     skipcount = 0;
  108.     if (argc > 3)
  109.     {
  110.         if (strcmp(argv[2],"-s") != 0)
  111.         {
  112.             usage();
  113.         }
  114.  
  115.         skipflag = TRUE;
  116.         skipcount = DEFAULT_SKIP;
  117.  
  118.         if (argc == 5)
  119.         {
  120.             skipcount = atoi(argv[3]);
  121.             if (skipcount < 0)
  122.             {
  123.                 usage();
  124.             }
  125.         }
  126.     }
  127.  
  128.     if (file_length < skipcount)
  129.         {
  130.             fprintf(stderr, "au2snd: skipped past end-of-file!\n\n");
  131.             exit(1);
  132.         }
  133.  
  134.     new_length = file_length - skipcount;
  135.  
  136.     /*** create a buffer for conversion of data ***/
  137.  
  138.     conv_buffer = malloc(new_length);
  139.  
  140.     if (!conv_buffer)
  141.     {
  142.         fprintf(stderr, "au2snd: Error allocating buffer (enough memory? need %d)", new_length);
  143.         exit(1);
  144.     }
  145.  
  146.     /*** move past 'skipcount' bytes and read file into buffer ***/
  147.  
  148.     fseek(infile, skipcount, SEEK_SET);
  149.  
  150.     fread(conv_buffer, sizeof(unsigned char), new_length, infile);
  151.  
  152.     fclose(infile) ;
  153.  
  154.     new_length = file_length - skipcount;
  155.  
  156.     my_registers.r[0] = 11;
  157.     my_registers.r[1] = (int) argv[argc - 1];
  158.     my_registers.r[2] = SAMPLE_FILETYPE;
  159.     my_registers.r[4] = 0;
  160.     my_registers.r[5] = new_length;
  161.  
  162.     fprintf(stderr,"au2snd: Output file %d byte", new_length + 1);
  163.     if ((new_length + 1) == 1)
  164.     {
  165.         fprintf(stderr, " long.\n");
  166.     }
  167.     else
  168.     {
  169.         fprintf(stderr, "s long.\n");
  170.     }
  171.  
  172.     if ((the_error = os_swix(OS_File, &my_registers)) != NULL)
  173.     {
  174.         fprintf(stderr,"au2snd: Error creating %s\n      Because: %s\n\n", 
  175.                                                 argv[argc - 1], the_error->errmess);
  176.         exit(1);
  177.     }
  178.  
  179.  
  180.     if ((outfile = fopen(argv[argc - 1], "rb+")) == NULL)
  181.     {
  182.         fprintf(stderr,"au2snd: Error opening %s\n",argv[argc - 1]);
  183.         exit(1);
  184.     }
  185.  
  186.     fprintf(stderr, "au2snd: Skipping %d byte", skipcount);
  187.     if (skipcount == 1)
  188.     {
  189.         fprintf(stderr, "\n");
  190.     }
  191.     else
  192.     {
  193.         fprintf(stderr, "s\n");
  194.     }
  195.  
  196.     /*** all the data is now in memory, so convert it ***/
  197.  
  198.     minch = INT_MAX;
  199.     maxch = INT_MIN;
  200.  
  201.     for(i = 0 ; i < new_length ; i++)
  202.     {
  203.         /*** convert uLAW to signed 8-bit ***/
  204.         ch = cvtback(conv_buffer[i]);
  205.         if (ch < minch)
  206.         {
  207.             minch = ch;
  208.         }
  209.         if (ch > maxch)
  210.         {
  211.             maxch = ch;
  212.         }
  213.     }
  214.  
  215.     amplif = 1;
  216.  
  217.     if (maxch != 0)
  218.     {
  219.         amplif = 127000 / maxch;
  220.     }
  221.  
  222.     if (minch != 0)
  223.     {
  224.         if (((-128000) / minch) < amplif)
  225.         {
  226.             amplif = (-128000) / minch;
  227.         }
  228.     }
  229.  
  230.     amplif = amplif - (1000 / 256);
  231.  
  232.     fprintf(stderr, "au2snd: Using amplification of %d.%.3d\n", amplif/1000, amplif % 1000);
  233.  
  234.     /*** cheap and nasty to get right sample rate ***/
  235.     fputc('}', outfile);
  236.  
  237.     /*** go back to beginning, and write out conversion ***/
  238.  
  239.     my_registers.r[0] = 1;
  240.     os_swi(Hourglass_Start, &my_registers);
  241.  
  242.     for(i = 0 ; i < new_length ; i++)
  243.     {
  244.         /*** convert uLAW to signed 8-bit ***/
  245.         conv_buffer[i] = (char) (cvtback(conv_buffer[i]) * amplif / 1000);
  246.  
  247.         if (!(i & 0x3ff))
  248.         {
  249.             my_registers.r[0] = (100 * i) / new_length;
  250.             os_swi(Hourglass_Percentage, &my_registers);
  251.         }
  252.     }
  253.  
  254.     my_registers.r[0] = 100;
  255.     os_swi(Hourglass_Percentage, &my_registers);
  256.  
  257.     fwrite(conv_buffer, sizeof(unsigned char), new_length, outfile);
  258.  
  259.     os_swi(Hourglass_Off, &my_registers);
  260.  
  261.     fclose(outfile) ;
  262.  
  263.     fprintf(stderr, "\n\n");
  264. }
  265.  
  266.